<template>
  <div class="root">
    <div class="left">
      <login-form />
      <div class="esync-form">
        <div class="buttons">
          <div class="field1">
          </div>
          <div class="field1">
            <button @click="get_server_info">获取服务器ID</button>
            <button @click="load_dev_list">加载终端列表</button>
            <button @click="get_disk_info">磁盘统计信息</button>
            <button @click="get_album_lists">相册列表</button>
            <button @click="get_file_lists">文件列表</button>
          </div>
        </div>
        <div class="field1">
          <input type="text" placeholder="brand" v-model="device_form.brand">
          <input type="text" placeholder="model" v-model="device_form.model">
          <button @click="get_my_device_info">获取终端ID</button>
        </div>
        <div class="field1">
          <input type="text" placeholder="device id" v-model="devID">
          <input type="text" placeholder="album name" v-model="album_form.name">
          <button @click="get_album_id">获取相册ID</button>
        </div>
        <div class="field1">
          <input type="text" placeholder="album id" v-model="albumID" />
          <button @click="get_album_info">相册信息</button>
          <file-uploader @selected="only_quick_upload" label="仅快速上传" />
          <file-uploader @selected="only_full_upload" label="仅全量上传" />
          <file-uploader @selected="upload_picture" label="图片上传" />
        </div>
        <div class="field1">
          <input type="text" placeholder="file id" v-model="fileID" />
          <button>缩略图</button>
          <button @click="get_raw_file">原图</button>
          <button>文件信息</button>
          <button @click="remove_file">删除文件</button>
        </div>
      </div>
      <div class="logger">
        <log-console :content="log_msg" :evtbus="evtbus" />
      </div>
    </div>
    <div class="right">
      <button @click="empty_picture">清空图片</button>
      <img :src="picture" class="downloaded-file" width="400" alt="" />
    </div>
  </div>
</template>

<script>
import LoginForm from './login';
import LogConsole from './logger';
import FileUploader from './uploader';

import esync from './requests';
import mixin from './mixin';
import {hex_sha1} from './sha1';

let crypto = require('crypto');
let fs = require('fs');

function checksumFile(hashName, path) {
  return new Promise((resolve, reject) => {
    const hash = crypto.createHash(hashName);
    const stream = fs.createReadStream(path);
    stream.on('error', err => reject(err));
    stream.on('data', chunk => hash.update(chunk));
    stream.on('end', () => resolve(hash.digest('hex')));
  });
}

// size 使用 8 字节存储 使用小端模式，存储 uint64 
// 由于 js 没有 uint64 的方法，所以严禁4G以上的文件，后4位 补0即可
function getFileHash(sha1, size) {
  if(size > 4000000000) {
    throw 'too big file';
  }
  let a1 = new Uint32Array([size]);
  let v1 = new Uint8Array(a1.buffer);

  let out = sha1;
  for(let i=0; i!==4; i++) {
    let cur = v1[i].toString(16);
    if(cur.length === 1) {
      cur = '0' + cur;
    }
    out += cur;
  }
  out += "00000000";
  return out;
}

export default {
  name: 'ESyncHome',
  mixins: [mixin],
  components: {
    LoginForm, LogConsole, FileUploader,
  },
  data() {
    return {
      devID: '',
      fileID: '',
      albumID: '',
      picture: '',
      device_form: {
        brand: '',
        model: '',
      },
      album_form: {
        name: ''
      }
    }
  },
  created() {
    //
  },
  methods: {
    get_raw_file() {
      let file_id = parseInt(this.fileID);
      if(isNaN(file_id)) {
        this.log('file id empty!');
        return;
      }
      esync.getRawFile(file_id).then(r=>{
        this.setPicData(r.data);
      });
    },
    get_album_info() {
      let album_id = parseInt(this.albumID, 10);
      if(!!!album_id || isNaN(parseInt(album_id))) {
        this.log('album id empty!');
        return;
      }

      this.show_promise(esync.getAlbumInfo(album_id)).then(r=>{
        this.picture = 'data:image/jpeg;base64,' + r.data.thumb;
      });
    },
    remove_file() {
      let file_id = parseInt(this.fileID);
      if(isNaN(file_id)) {
        this.log('file id empty!');
        return;
      }
      this.show_promise(esync.removeFile(file_id));
    },
    upload_video(file) {},
    upload_picture(file) {},
    async only_quick_upload(file) {
      let album_id = this.albumID;
      if(!!!album_id || isNaN(parseInt(album_id))) {
        this.log('album id empty!');
        return;
      }

      console.log(file);
      let sha1 = await checksumFile('sha1', file.path);
      let file_size = file.size;
      let name = file.name;
      let hash = getFileHash(sha1, file_size);
      console.log('file hash: ' + hash);

      let form = {
        file_name: name,
        hash: hash,
      }
     this.show_promise(esync.quickUpload(parseInt(album_id, 10), form));
    },
    async only_full_upload(file) {
      let album_id = this.albumID;
      if(!!!album_id || isNaN(parseInt(album_id))) {
        this.log('album id empty!');
        return;
      }
      console.log(file);
      let sha1 = await checksumFile('sha1', file.path);
      let file_size = file.size;
      let name = file.name;
      let hash = getFileHash(sha1, file_size);
      console.log('file hash: ' + hash);

      let formData = new FormData();
      formData.append('file', file);
      formData.append('file_name', name);
      formData.append('hash', hash);
     this.show_promise(esync.fullUpload(parseInt(album_id, 10), formData));
    },
    get_file_lists() {
      let album_id = parseInt(this.albumID, 10);
      if(!!!album_id || isNaN(parseInt(album_id))) {
        this.log('album id empty!');
        return;
      }
      this.show_promise(esync.getFileLists(album_id));
    },
    get_album_id() {
      let devID = this.devID;
      let name = this.album_form.name;
      if(!!!devID || !!!name) {
        this.log('devID empty or name empty');
        return;
      }
      this.show_promise(esync.fetchAlbumInfo({
        device_id: parseInt(devID),
        name: name,
      }));
    },
    get_album_lists() {
      this.show_promise(esync.getAlbumLists());
    },
    show_promise(r) {
      r.then(res=>{
        this.log(JSON.stringify(res.data));
        return res;
      }).catch(err=>{
        let rsp = err.response;
        if(!!!rsp) {
          this.log('empty response');
          this.log(err);
          return;
        }
        let data = rsp.data;
        if(!!!data) {
          this.log('empty data');
          this.log(err);
          return;
        }
        let code = data.code;
        let msg = data.msg;
        this.log(`ERROR: ${code}, ${msg}`);
        throw err;
      });
      return r;
    },
    get_disk_info() {
      this.show_promise(esync.getServerDiskInfo());
    },
    load_dev_list() {
      this.show_promise(esync.getDeviceList());
    },
    get_my_device_info() {
      let model = this.device_form.model;
      let brand = this.device_form.brand;
      if(!!!model || !!!brand) {
        this.log('model empty or brand empty');
        return;
      }
      let hash = hex_sha1(model + brand);
      let form = {
        model,
        brand,
        hash,
      };
      this.show_promise(esync.fetchDeviceInfo(form));
    },
    get_server_info() {
      this.show_promise(esync.getServerInfo());
    },
    upload_picture() {
      this.$refs._upload_input.dispatchEvent(new MouseEvent('click'));
    },
    setPicData(data) {
      let reader = new FileReader();
      reader.readAsDataURL(data);
      reader.onload = () => {
        this.picture = reader.result;
      }
    },
    empty_picture() {
      this.picture = '';
    },
  }
}
</script>

<style scoped>
div.root {
  display: flex;
  flex-direction: row;
}
div.left {
  flex: 5;
}
div.right {
  flex: 3;
}
.field1, .login-form {
  margin-bottom: 10px;
}
</style>
